package com.example.mtblog.controller;


import cn.hutool.core.util.IdUtil;
import com.example.mtblog.common.Result;
import com.example.mtblog.common.common;
import com.example.mtblog.dto.LoginUser;
import com.example.mtblog.dto.ResUser;
import com.example.mtblog.dto.UserDTO;
import com.example.mtblog.entity.User;
import com.example.mtblog.mapper.UserMapper;
import com.example.mtblog.service.UserService;
import com.example.mtblog.tool.RedisUtils;
import com.example.mtblog.tool.TokenUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author MT
 * @since 2023-10-293
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    UserMapper userMapper;

    @Resource
    UserService userService;

    @Resource
    PasswordEncoder passwordEncoder;

    @Resource
    private AuthenticationManager authenticationManager;

    /**
     * @description: 快速注册
     * @author MT
     * @date 2023/10/23 14:03
     * @version 1.0
     */


    public User fastRegister() {
        User user = new User();
        String UUID = IdUtil.fastSimpleUUID();
        user.setUsername("blog_id" + UUID);
        user.setPassword(passwordEncoder.encode("123456"));

        user = userService.initUser(user);
        return user;
    }



    @PostMapping("/register")
    public Result<?> registerUser(@RequestBody User user) {

        //判断账号是否已经注册
        Boolean res = userService.isCreated("username", user.getUsername());
        if (res)
            return Result.error("用户已存在");


        String newPassword = passwordEncoder.encode(user.getPassword()); //加密之后的密码


        try {
            user = userService.initUser(user);
            user.setPassword(newPassword);
            userMapper.insert(user);
        } catch (Exception e) {
            log.error(e + " --  user -> register");
            return Result.error("error in  -- user -> register" + e);
        }

        return Result.success(user);
    }

    /**
     * Description: 登录功能
     * date: 2023/6/9
     * author: MT
     */

    @PostMapping("/login")
    public Result<?> loginUser(@RequestBody User user) {

        if (user.getUid() == null || user.getPassword() == null)
            return Result.error("用户ID或密码不能为空");


        Authentication authentication;
        try {
            authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(user.getUid(), user.getPassword()));

            if (Objects.isNull(authentication))
                return Result.error("用户ID或者密码错误");

        } catch (Exception e) {
            String errorMsg = "error in login " + "\n" + e;
            log.error(errorMsg);
            return Result.error("用户ID或者密码错误");
        }

        //验证成功生成Token
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        loginUser.setPassword(user.getPassword());
        String token = TokenUtils.createToken(loginUser);

        //ResUser 返回给前端的实体

        return Result.success(new ResUser(loginUser.getUser(), token),"登录成功");
    }


    @GetMapping("/loginByWX")
    public Result<?> loginByWX(@RequestParam(value = "code") String code) {


        Result<?> res = userService.loginByWX(code);

        if (res.getCode() != 200)
            return res;

        String openid = (String) res.getData();

        User user = userService.selectBy("openid", openid);


        String msg = "登录成功";

        try {
            //未绑定微信，先注册
            if (user == null) {
                user = fastRegister();
                user.setOpenid(openid);
                userMapper.insert(user);
                msg = "首次登录者快速完成注册";
            }

            //登录
            LoginUser loginUser = new LoginUser(user);
            String token = TokenUtils.createToken(loginUser);

            return Result.success(new ResUser(loginUser.getUser(), token), msg);
        } catch (Exception e) {
            String errorMsg = "error in user/loginByWX " + "\n" + e;
            log.error(errorMsg);
            return Result.error(errorMsg);
        }
    }


    /**
     * Description: 退出登录
     * date: 2023/6/9
     * author: MT
     */

    @PostMapping("/logout")
    public Result<?> logoutUser(){

        try {
            UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
            LoginUser loginUser = (LoginUser) authentication.getPrincipal();

//            System.out.println("uid :"+loginUser.getUsername());

            String tokenKey ="loginToken:"+ loginUser.getUUID();

            if(!RedisUtils.deleteObject(tokenKey))
                return  Result.success(null,"该账号已失效");

        }catch (Exception e){
            log.error(String.valueOf(e));
            log.error("error found in LoginContoller -> louout");
            return  Result.error("退出失败");
        }

        //ResUser 返回给前端的实体
        return  Result.success(null,"退出成功");
    }

    /**
     * Description: 修改资料
     * date: 2023/6/9
     * author: MT
     */

    @PostMapping("/edit")
    public Result<?> editUser(@RequestBody User user , HttpServletRequest request){

        User oldUser = null ;
        try {
           Integer uid = common.getLoginUid(request);

           if( ! Objects.equals(uid,user.getUid()))
               return Result.error("请求错误,别搞小动作");


           oldUser = userMapper.selectById(uid);
           oldUser = userService.editUserBaseInfo(user,oldUser);
           userMapper.updateById(oldUser);

           oldUser.setPassword(user.getPassword());


        }catch (Exception e){
            log.error(String.valueOf(e));
            log.error("error found in LoginContoller -> editUser");
            return  Result.error("用户修改失败");
        }

        //ResUser 返回给前端的实体
        return  Result.success(new UserDTO(oldUser),"修改成功");
    }
}

